package com.tlgen.modules.vocation.service.impl;

import com.tlgen.common.exception.EntityExistException;
import com.tlgen.common.utils.FileUtil;
import com.tlgen.common.utils.PageUtil;
import com.tlgen.common.utils.QueryHelp;
import com.tlgen.common.utils.ValidationUtil;
import com.tlgen.modules.vocation.domain.Family;
import com.tlgen.modules.vocation.repository.FamilyRepository;
import com.tlgen.modules.vocation.service.FamilyService;
import com.tlgen.modules.vocation.service.dto.FamilyDto;
import com.tlgen.modules.vocation.service.dto.FamilyQueryCriteria;
import com.tlgen.modules.vocation.service.mapper.FamilyMapper;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

@Service
@CacheConfig(cacheNames = "Family")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class FamilyServiceImpl implements FamilyService {

    private final FamilyRepository familyRepository;

    private final FamilyMapper familyMapper;

    public FamilyServiceImpl(FamilyRepository familyRepository, FamilyMapper familyMapper) {
        this.familyRepository = familyRepository;
        this.familyMapper = familyMapper;
    }

    /**
     * 根据登记人员名称获取信息
     * @param record
     * @return
     */
    @Override
    @Cacheable(key = "'loadUserByUsername:'+#p0")
    public FamilyDto findByName(String record) {
        Family family;
        family = familyRepository.findByRecord(record);
        if(family==null){
            throw new EntityExistException(Family.class,"record",record);
        }else {
            return familyMapper.toDto(record);
        }
    }

    /**
     * 不带条件分页查询
     * @param pageable 分页参数
     * @return
     */
    @Override
    @Cacheable
    public Object queryAll(Pageable pageable) {
        return familyMapper.toDto(familyRepository.findAll(pageable).getContent());
    }


    /**
     * 带条件分页查询
     * @param criteria 条件
     * @param pageable 分页参数
     * @return
     */
    @Override
    @Cacheable
    public Object queryAll(FamilyQueryCriteria criteria, Pageable pageable) {
        Page<Family> page = familyRepository.findAll((root, criteriaQuery, criteriaBuilder) ->
                QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(familyMapper::toDto));
    }

    /**
     * 带条件不分页查询
     * @param criteria 条件
     * @return
     */
    @Override
    @Cacheable
    public List<FamilyDto> queryAll(FamilyQueryCriteria criteria) {
        return familyMapper.toDto(familyRepository.findAll((root, criteriaQuery, criteriaBuilder) ->
                QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    /**
     * 新增
     * @param resources /
     * @return
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public FamilyDto create(Family resources) {
        if (familyRepository.findByRecord(resources.getRecord()) != null) {
            throw new EntityExistException(Family.class, "record", resources.getRecord());
        }
        return familyMapper.toDto(familyRepository.save(resources));
    }

    /**
     * 编辑
     * @param resources /
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void update(Family resources) {
        Family Family = familyRepository.findById(resources.getId()).orElseGet(Family::new);
        ValidationUtil.isNull(Family.getId(),"Family","id",resources.getId());

        Family.setCountygroup(resources.getCountygroup());
        Family.setAttr(resources.getAttr());
        Family.setAddress(resources.getAddress());
        Family.setRecord(resources.getRecord());
        Family.setFamilyid(resources.getFamilyid());
        Family.setNum(resources.getNum());
        Family.setAttr(resources.getAttr());
        Family.setCount(resources.getCount());
        Family.setCreatetime(resources.getCreatetime());
        Family.setJ_area(resources.getJ_area());
        familyRepository.save(Family);
    }

    /**
     * 删除
     * @param ids /
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void delete(Set<Long> ids) {
        for (Long id : ids) {
            familyRepository.deleteById(id);
        }
    }

    /**
     * 导出数据
     * @param response /
     * @throws IOException
     */
    @Override
    public void download(List<FamilyDto> FamilyDtos, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (FamilyDto FamilyDto : FamilyDtos) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("村组", FamilyDto.getCountygroup());
            map.put("户属性", FamilyDto.getAttr());
            map.put("地址", FamilyDto.getAddress());
            map.put("登记人员", FamilyDto.getRecord());
            map.put("区域", FamilyDto.getFamilyid());
            map.put("家庭人口数", FamilyDto.getNum());
            map.put("农业人口数", FamilyDto.getCount());
            map.put("创建时间", FamilyDto.getCreatetime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    /**
     * 根据Id查询
     * @param id /
     * @return
     */
    @Override
    @Cacheable(key = "#p0")
    public FamilyDto findById(long id) {
        Family family = familyRepository.findById(id).orElseGet(Family::new);
        ValidationUtil.isNull(family.getId(),"Family","id",id);
        return familyMapper.toDto(family);
    }
    /**
     * 修改角色成员关系
     * @param resources /
     * @param familyDto /
     */
    @Override
    @CacheEvict(allEntries = true)
    public void updateHome(Family resources, FamilyDto familyDto) {
        Family family = familyMapper.toEntity(familyDto);
        family.setHomes(resources.getHomes());
        familyRepository.save(family);
    }

}
